package com.cory.boot.support.redis;

import java.lang.reflect.Method;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import com.cory.boot.component.cache.RedisUtils;
import com.cory.boot.domain.CustomRuntimeException;
import com.cory.boot.support.redis.annotation.RedisLock;


/**
 * @author xiongcong
 * @date 2023-05-05
 */
@Aspect
@Component
public class RedisLockAspect {

    @Around("@annotation(com.cory.boot.support.redis.annotation.RedisLock)")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        
        RedisLock annotation = method.getAnnotation(RedisLock.class);
        return RedisUtils.lock(annotation.key(), annotation.seconds(), () -> {
            try {
                return pjp.proceed();
            } catch (CustomRuntimeException e) {
                throw e;
            } catch (Throwable e) {
                throw new RuntimeException(e);
            }
            
        });
    }
}
